﻿using System;
using System.Collections.Generic;
using FireFly;
using System.Reflection;
using System.Linq;

namespace XAMLStylePad.ViewModels
{
    public class TypeViewModel: ViewModelBase<Type>
    {
        internal TypeViewModel(Type type): base(type)
        {
            SelectedConstructor = Constructors.FirstOrDefault();
            //OnPropertyChanged("Selec")
        }
        
        public override string DisplayName
        {
            get { return Model.Name; }
        }

        //public string NewInstanceName 
        //{ 
        //    get; 
        //    set; 
        //}

        #region Constructors
        public CollectionViewModel<ConstructorInfo, ConstructorViewModel> Constructors
        {
            get
            {
                if(_Constructors == null)
                {
                    _Constructors = new CollectionViewModel<ConstructorInfo, ConstructorViewModel>(Model.GetConstructors(), "Constructors", CollectionShowMode.UserFriendly, model =>
                    {
                        var viewModel = new ConstructorViewModel(model);
                        return viewModel;
                    }) ;
                }
                return _Constructors;
            }
        }
        CollectionViewModel<ConstructorInfo, ConstructorViewModel> _Constructors;
        #endregion

        public ConstructorViewModel SelectedConstructor { get; set; }

        #region Properties
        public CollectionViewModel<PropertyInfo, PropertyViewModel> Properties
        {
            get
            {
                if(_Properties == null)
                {
                    _Properties = new CollectionViewModel<PropertyInfo, PropertyViewModel>(Model.GetProperties(), "Properties", CollectionShowMode.UserFriendly, model =>
                    {
                        var viewModel = new PropertyViewModel(model);
                        return viewModel;
                    });
                }
                return _Properties;
            }
        }
        CollectionViewModel<PropertyInfo, PropertyViewModel> _Properties;
        #endregion

        #region Fields
        public CollectionViewModel<FieldInfo, FieldViewModel> Fields
        {
            get
            {
                if(_Fields == null)
                {
                    _Fields = new CollectionViewModel<FieldInfo, FieldViewModel>(Model.GetFields(), "Fields", CollectionShowMode.UserFriendly, model =>
                    {
                        var viewModel = new FieldViewModel(model);

                        return viewModel;
                    });
                }
                return _Fields;
            }
        }
        CollectionViewModel<FieldInfo, FieldViewModel> _Fields;
        #endregion

        public object CreateInstance()
        {
            object newObj = null;
            var ctor = SelectedConstructor;

            if(ctor != null)
            {
                List<object> values = new List<object>();

                if(ctor.Parameters != null)
                    foreach(var item in ctor.Parameters)
                        values.Add(item.Value);

                newObj = ctor.CreateObject(values.ToArray());
            }

            // if it's struct
            if(newObj == null && Model.IsValueType && !Model.IsPrimitive && !Model.IsEnum)
            {
                newObj = Activator.CreateInstance(Model);
            }

            if(newObj != null)
            {
                foreach(var prop in Properties)
                {
                    prop.SetValueForInstance(newObj);
                }

                foreach(var field in Fields)
                {
                    field.SetValueForInstance(newObj);
                }
            }

            return newObj;
        }

        public bool IsCtorsVisible
        {
            get
            {
                var res = !(Model.IsEnum || Constructors == null || Constructors.Count == 0);
                return res;
            }
        }

        public bool IsMembersVisible
        {
            get
            {
                return !IsCtorsVisible;
            }
        }
            
        public string ErrorMessage{ 
            get
            {
                return _error;
            }
            set
            {
                _error = value;
                OnPropertyChanged("ErrorMessage");
            }
        }   
        string _error = null;
    }
}